package com.neusoft.grid.controller;

import com.neusoft.grid.entity.Mission;
import com.neusoft.grid.entity.AQI;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MissionSubmitViewController {

    @FXML
    private Label lblReporter;
    @FXML
    private Label lblPhone;
    @FXML
    private Label lblGrid;
    @FXML
    private Label lblLocation;
    @FXML
    private Label lblLevel;
    @FXML
    private Label lblDescription;
    @FXML
    private Label lblAQILevel;

    @FXML
    private TextField txtSO2;
    @FXML
    private TextField txtCO;
    @FXML
    private TextField txtPM25;

    private Mission currentMission;
    private GridMissionViewController parentController;
    private static final String AQI_FILE = "src/com/neusoft/grid/data/AQI.txt";

    public void initData(Mission mission, GridMissionViewController parentController) {
        this.currentMission = mission;
        this.parentController = parentController;
        lblReporter.setText(mission.getReporter());
        lblPhone.setText(mission.getPhone());
        lblGrid.setText(mission.getGrid());
        lblLocation.setText(mission.getLocation());
        lblLevel.setText(mission.getLevel());
        lblDescription.setText(mission.getDescription());

        txtSO2.textProperty().addListener((obs, oldVal, newVal) -> calculateAQI());
        txtCO.textProperty().addListener((obs, oldVal, newVal) -> calculateAQI());
        txtPM25.textProperty().addListener((obs, oldVal, newVal) -> calculateAQI());
    }

    @FXML
    private void handleSubmit() {
        try {
            int so2 = txtSO2.getText().isEmpty() ? 0 : Integer.parseInt(txtSO2.getText());
            int co = txtCO.getText().isEmpty() ? 0 : Integer.parseInt(txtCO.getText());
            int pm25 = txtPM25.getText().isEmpty() ? 0 : Integer.parseInt(txtPM25.getText());

            // 从 currentMission 中获取年和月
            String yearStr = currentMission.getYear();
            String monthStr = currentMission.getMonth();

            // 验证年和月是否有效
            if (yearStr == null || yearStr.isEmpty() || monthStr == null || monthStr.isEmpty()) {
                lblAQILevel.setText("任务中缺少年份或月份信息");
                lblAQILevel.setStyle("-fx-text-fill: red;");
                return;
            }

            int year = Integer.parseInt(yearStr);
            int month = Integer.parseInt(monthStr);

            int aqiValue = calculateAQI(so2, co, pm25);
            String level = getAQILevel(aqiValue);

            AQI aqiRecord = new AQI(so2, co, pm25, aqiValue, year, month);

            saveAQIData(aqiRecord);

            lblAQILevel.setText(String.format("AQI等级: %d (%s)", aqiValue, level));
            lblAQILevel.setStyle("-fx-text-fill: #2196F3;");

            System.out.println("提交数据成功: " + currentMission);
            System.out.println("SO2浓度: " + so2 + " μg/m³");
            System.out.println("CO浓度: " + co + " μg/m³");
            System.out.println("PM2.5浓度: " + pm25 + " μg/m³");
            System.out.println("计算AQI: " + aqiValue);

            closeWindow();

        } catch (NumberFormatException e) {
            lblAQILevel.setText("请输入有效数字");
            lblAQILevel.setStyle("-fx-text-fill: red;");
        } catch (IOException e) {
            System.err.println("保存数据失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private void saveAQIData(AQI newRecord) throws IOException {
        List<AQI> aqiList = loadAQIData();
        aqiList.add(newRecord);

        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(AQI_FILE))) {
            oos.writeObject(aqiList);
        }
    }

    @SuppressWarnings("unchecked")
    private List<AQI> loadAQIData() throws IOException {
        File file = new File(AQI_FILE);
        if (!file.exists() || file.length() == 0) {
            return new ArrayList<>();
        }

        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
            return (List<AQI>) ois.readObject();
        } catch (ClassNotFoundException e) {
            throw new IOException("数据文件格式错误", e);
        }
    }

    private void calculateAQI() {
        try {
            double so2 = txtSO2.getText().isEmpty() ? 0 : Double.parseDouble(txtSO2.getText());
            double co = txtCO.getText().isEmpty() ? 0 : Double.parseDouble(txtCO.getText());
            double pm25 = txtPM25.getText().isEmpty() ? 0 : Double.parseDouble(txtPM25.getText());

            int aqi = calculateAQI(so2, co, pm25);
            String level = getAQILevel(aqi);

            lblAQILevel.setText(String.format("AQI等级: %d (%s)", aqi, level));
            lblAQILevel.setStyle("-fx-text-fill: #2196F3;");

        } catch (NumberFormatException e) {
            lblAQILevel.setText("请输入有效数字");
            lblAQILevel.setStyle("-fx-text-fill: red;");
        }
    }

    private int calculateAQI(double so2, double co, double pm25) {
        int iaqiSO2 = calculateIAQI(so2, new int[] { 0, 50, 150, 475, 800, 1600, 2100, 2620 });
        int iaqiCO = calculateIAQI(co, new int[] { 0, 2, 4, 14, 24, 36, 48, 60 });
        int iaqiPM25 = calculateIAQI(pm25, new int[] { 0, 35, 75, 115, 150, 250, 350, 500 });
        return Math.max(Math.max(iaqiSO2, iaqiCO), iaqiPM25);
    }

    private int calculateIAQI(double c, int[] bp) {
        if (c <= bp[1])
            return linearInterp(c, bp[0], bp[1], 0, 50);
        else if (c <= bp[2])
            return linearInterp(c, bp[1], bp[2], 50, 100);
        else if (c <= bp[3])
            return linearInterp(c, bp[2], bp[3], 100, 150);
        else if (c <= bp[4])
            return linearInterp(c, bp[3], bp[4], 150, 200);
        else if (c <= bp[5])
            return linearInterp(c, bp[4], bp[5], 200, 300);
        else if (c <= bp[6])
            return linearInterp(c, bp[5], bp[6], 300, 400);
        else
            return c > bp[6] ? 500 : 0;
    }

    private int linearInterp(double c, double cLow, double cHigh, int iLow, int iHigh) {
        return (int) ((iHigh - iLow) / (cHigh - cLow) * (c - cLow) + iLow);
    }

    private String getAQILevel(int aqi) {
        if (aqi <= 50)
            return "一级 优";
        else if (aqi <= 100)
            return "二级 良";
        else if (aqi <= 150)
            return "三级 轻度污染";
        else if (aqi <= 200)
            return "四级 中度污染";
        else if (aqi <= 300)
            return "五级 重度污染";
        else
            return "六级 严重污染";
    }

    @FXML
    private void handleCancel() throws IOException {
        closeWindow();
    }

    private void closeWindow() throws IOException {
        File file = new File("src/com/neusoft/grid/data/nowMission.txt");
        if (!file.exists()) {
            System.err.println("任务文件 nowMission.txt 不存在");
            return;
        }
        String nowMission = null;
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
            try {
                nowMission = (String) ois.readObject();
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
        } catch (IOException e) {
            System.err.println("读取任务文件失败: " + e.getMessage());
            e.printStackTrace();
        }
        System.out.println(nowMission);
        file = new File("src/com/neusoft/grid/data/mission.txt");
        if (!file.exists()) {
            System.err.println("任务文件 mission.txt 不存在");
            return;
        }
        Map<String, Mission> missionMap = new HashMap<>();
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
            try {
                missionMap = (Map<String, Mission>) ois.readObject();
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
        } catch (IOException e) {
            System.err.println("读取任务文件失败: " + e.getMessage());
            e.printStackTrace();
        }
        for (Map.Entry<String, Mission> entry : missionMap.entrySet()) {
            String key = entry.getKey();
            Mission value = entry.getValue();
            System.out.println(key + "：" + value);
        }
        //System.out.println(missionMap.get(nowMission).getNumber());
        FileOutputStream fos = new FileOutputStream(file);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        missionMap.remove(nowMission);
        oos.writeObject(missionMap);
        System.out.println(missionMap.size());
        if (parentController != null) {
            parentController.refreshMissionList();
        }
        Stage stage = (Stage) txtCO.getScene().getWindow();
        stage.close();
    }
}